<template xmlns:v-contextmenu="http://www.w3.org/1999/xhtml">
    <div ref="node" class="node" v-contextmenu:contextmenu :style="{'left': node.meta.x + 'px', 'top': node.meta.y + 'px'}" @click="SetCurrentNode(node.meta.id)">
        <Icon :type="iconType" size="16" style="color: #2d8cf0; margin: 0 2px"/>

        <Select v-if="iconType === 'md-options'" class="condition-select" size="small" @on-change="selectFactor" :transfer="true" :disabled="editable">
            <Option v-for="factor in factorOptions" :value="factor | serialize" :key="factor.variableName">{{ factor.variableLabel }}</Option>
        </Select>
        <Select v-if="iconType === 'md-information-circle'" class="operator-select" size="small" @on-change="selectOperator" @on-open-change="checkOperatorOptions" :transfer="true" v-model="operator" :disabled="editable">
            <Option v-for="item in operatorOptions" :value="item.opTypeEnName" :key="item.opTypeEnName">{{ item.opTypeCnName }}</Option>
        </Select>
        <Input v-if="iconType === 'md-information-circle' && valueInputVisible" class="value-input" size="small" v-model="input" @on-blur="afterInput" :disabled="editable"/>
        <Button v-if="iconType === 'ios-construct'" class="action-btn" type="dashed" size="small" @click="startActionSet">点击添加动作</Button>
        <v-contextmenu ref="contextmenu" @show="SetCurrentNode(node.meta.id)">
            <v-contextmenu-item @click="addCondition" v-if="conditionMenuVisible && iconType !== 'ios-construct' && iconType !== 'md-information-circle'">添加条件</v-contextmenu-item>
            <v-contextmenu-item @click="addAction" v-if="actionMenuVisible && iconType !== 'ios-construct' && iconType !== 'md-options'">添加动作</v-contextmenu-item>
            <v-contextmenu-item @click="addVariable" v-if="variableMenuVisible && iconType === 'md-information-circle'">添加变量</v-contextmenu-item>
            <v-contextmenu-item @click="removeNode">删除节点</v-contextmenu-item>
        </v-contextmenu>
        <Modal title="设置动作" v-model="actionPanelVisible" :mask-closable="false" @on-ok="setAction">
            <div>
                <Spin fix v-if="loading">
                    <Icon type="ios-loading" size="18" class="spin-icon-load"></Icon>
                    <div>Loading</div>
                </Spin>
                <Form ref="actionForm" :label-width="80">
                    <FormItem v-for="action in actionData" :label="action.variableLabel" :key="action.variableName">
                        <Input type="text" v-model.number="action.variableValue" :name="action.variableName" :disabled="editable"></Input>
                    </FormItem>
                </Form>
            </div>
        </Modal>
    </div>
</template>

<script>
    import * as NodeType from '@/lib/node-type'
    import {mapActions, mapGetters} from 'vuex'
    export default {
        name: "Node",
        props: {
            node: {
                type: Object,
                required: true
            }
        },
        data() {
            return {
                iconType: 'md-information-circle',
                factorOptions: [],
                operatorOptions: [],
                valueInputVisible: false,
                actionMenuVisible: true,
                conditionMenuVisible: true,
                variableMenuVisible: true,
                actionPanelVisible: false,
                loading: false,
                // 条件节点的操作符
                operator: '',
                // 条件节点的用户输入值
                input: '',
                actionData: [],
                editable: false
            }
        },
        methods: {
            ...mapGetters(['factors', 'operators', 'actions']),
            ...mapActions(['AddNode', 'RemoveNode', 'SetCurrentNode', 'FetchFactors', 'FetchOperators', 'FetchActions', 'ReCalculateChildrenX', 'SetNodeData']),
            async fetchFactors() {
                await this.FetchFactors()
                this.factorOptions = this.factors()
            },
            async selectFactor(value) {
                this.changeWidth()
                this.setNodeData(this.node, JSON.parse(value))
            },
            async fetchOperators() {
                let parent = this.node.parent
                if (parent && parent.data) {
                    // 请求操作符
                    let params = {varType: parent.data.variableType}
                    await this.FetchOperators(params)
                    this.operatorOptions = this.operators()
                }
            },
            selectOperator(value) {
                this.changeWidth()
                // 显示输入
                this.valueInputVisible = true
                let data = {op: this.operator, param: this.input}
                this.setNodeData(this.node, data)
            },
            afterInput() {
                let data = {op: this.operator, param: this.input}
                this.setNodeData(this.node, data)
            },
            // 设置当前节点的宽度
            changeWidth() {
                let originWidth = this.node.width
                let _vm = this
                this.$nextTick(() => {
                    let width = _vm.$refs['node'].clientWidth
                    _vm.node.setWidth(width)
                    _vm.ReCalculateChildrenX()
                    _vm.$emit('ex')
                })
            },
            setNodeData(node, data) {
                this.SetNodeData({node, data})
            },
            addCondition() {
                this.AddNode(NodeType.CONDITION);
                this.actionMenuVisible = false
            },
            addAction() {
                this.AddNode(NodeType.ACTION);
                this.actionMenuVisible = false
                this.conditionMenuVisible = false
                this.variableMenuVisible = false
            },
            addVariable() {
                this.AddNode(NodeType.VARIABLE);
                this.actionMenuVisible = false
            },
            removeNode() {
                this.RemoveNode(this.node)
                let _vm = this
                this.$nextTick(() => {
                    _vm.$emit('ex')
                })
            },
            checkOperatorOptions(open) {
                if (open) {
                    if (this.operatorOptions.length === 0) {
                        let _vm = this
                        this.notice('请选择上一级节点的数据')
                        this.$nextTick(() => {
                            _vm.fetchOperators()
                        })
                    }
                }
            },
            async startActionSet() {
                this.actionPanelVisible = true
                await this.FetchActions()
                this.actionData = this.actions()
            },
            notice (msg) {
                this.$Notice.warning({
                    title: '警告',
                    desc: msg
                });
            },
            setAction() {
                this.setNodeData(this.node, this.actionData)
            }
        },
        mounted() {
            let type = this.node.type
            switch (type) {
                case NodeType.CONDITION:
                    this.iconType = 'md-information-circle'
                    this.fetchOperators()
                    break
                case NodeType.VARIABLE:
                    this.iconType = 'md-options'
                    this.fetchFactors()
                    break
                case NodeType.ACTION:
                    this.iconType = 'ios-construct'
                    break
            }
            this.changeWidth()
        },
        filters: {
            serialize(object) {
                return JSON.stringify(object)
            }
        }
    }
</script>

<style lang="scss">
    .node {
        background-color: #fff;
        position: absolute;
        padding: 4px;
        border-radius: 5px;
        display: inline;
        border: 1px solid #ed4014;
        .condition-select {
            max-width: 100px;
            &.ivu-select {
                width: auto;
            }
            .ivu-select-selection {
                border: none;
                box-shadow: none;
            }
            .ivu-select-selection:hover {
                border: 1px dashed #888;
            }
            .ivu-select-selected-value {
                padding: 2px;
                text-align: center;
                line-height: 20px !important;
            }
            .ivu-icon {
                display: none;
            }
        }
        .operator-select {
            &.ivu-select {
                width: auto;
            }
            .ivu-select-selection {
                border: none;
                box-shadow: none;
            }
            .ivu-select-selection:hover {
                border: 1px dashed #888;
            }
            .ivu-select-selected-value {
                padding: 2px;
                text-align: center;
                line-height: 20px !important;
            }
            .ivu-icon {
                display: none;
            }
        }
        .value-input {
            .ivu-input-small {
                border: none;
                box-shadow: none;
            }
            .ivu-input-small:hover {
                border: 1px dashed #888;
            }
            .ivu-input-wrapper {
                width: auto;
            }
            max-width: 80px;
        }
        .action-btn {
            box-shadow: none;
        }

    }

    .spin-icon-load{
        animation: ani-spin 1s linear infinite;
    }

    .spin-col{
        height: 100px;
        position: relative;
        border: 1px solid #eee;
    }

    @keyframes ani-spin {
        from { transform: rotate(0deg);}
        50%  { transform: rotate(180deg);}
        to   { transform: rotate(360deg);}
    }
</style>